use frag;
use geom;
use signal;

use super::core::{
  GUI, LiveTree, GUIContext,
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// GUI live+underlying tree

pub struct LiveGUI {
  size: geom::Dim,
  frag: frag::Frag,
  live_tree: LiveTree,
  cb_map: signal::CallbackMap<LiveTree>,
}

impl LiveGUI {

  pub fn new(size: geom::Dim, app: GUI) -> LiveGUI {
    let mut frag = frag::Frag::default();
    let mut live_tree = LiveTree::frag();
    let mut cb_map = signal::CallbackMap::new();

    // impose the initial tree
    let mut ctx = GUIContext::new(cb_map.registrar());
    live_tree.impose(app.0, &mut frag, &mut ctx);

    // create LiveGUI and calculate initial appearance
    let mut ui = LiveGUI { size, frag, live_tree, cb_map };
    ui.recalc();
    ui
  }

  pub fn root_frag(&self) -> &frag::Frag { &self.frag }

  pub fn set_size(&mut self, size: geom::Dim) {
    self.size = size;
    self.recalc();
  }

  pub fn fire_click_evt(&mut self, pos: geom::Pos) {
    let dsp = self.cb_map.dispatcher(&mut self.live_tree);
    self.frag.fire_click_evt(dsp, pos);
    self.recalc();
  }

  fn recalc(&mut self) {
    self.frag.calculate_geometry(self.size);
  }
}
